`timescale 1ns / 1ps

`include "data_width.vh"

module double_mem_interface #(parameter
    MEM_AWIDTH = `MEM_AWIDTH,
    MEM_DWIDTH = `MEM_DWIDTH
    ) (
        input                               clk,
        input                               front_rst,
        input [MEM_AWIDTH - 1 : 0]          edge_off_addr,
        input                               edge_off_addr_valid,
        input [MEM_AWIDTH - 1 : 0]          edge_info_addr,
        input                               edge_info_addr_valid,
        input                               mem_full,
        input [MEM_DWIDTH * 2 - 1 : 0]      mem_data_offset,
        input [MEM_DWIDTH * 2 - 1 : 0]      mem_data_info,
        input [MEM_DWIDTH * 2 - 1 : 0]      mem_data_degree,
        input [MEM_AWIDTH - 1 : 0]          mem_addr_offset,
        input [MEM_AWIDTH - 1 : 0]          mem_addr_info,
        input                               mem_data_valid_offset,
        input                               mem_data_valid_info,

        output reg                          rst,
        output                              addr_buffer_full,
        output reg [MEM_DWIDTH * 2 - 1 : 0] mem_data_to_edge_off,
        output reg                          mem_data_valid_to_edge_off,
        output reg [MEM_DWIDTH * 2 - 1 : 0] mem_data_to_edge_info,
        output reg [MEM_DWIDTH * 2 - 1 : 0] mem_data_to_edge_degree,
        output reg                          mem_data_valid_to_edge_info,
        output [MEM_AWIDTH - 1 : 0]         addr_offset,
        output [MEM_AWIDTH - 1 : 0]         addr_info,
        output                              addr_offset_valid,
        output                              addr_info_valid);

    always @ (posedge clk) begin
        rst <= front_rst;
    end

    addr_32bit_fifo aof (
        .clk(clk), .srst(front_rst),
        .din(edge_off_addr), .wr_en(edge_off_addr_valid), .rd_en(!mem_full),

        .dout(addr_offset), .valid(addr_offset_valid),
        .empty(buffer_empty_offset), .prog_full(buffer_full_offset));

    addr_32bit_fifo addr_info_f (
        .clk(clk), .srst(front_rst),
        .din(edge_info_addr), .wr_en(edge_info_addr_valid), .rd_en(!mem_full),

        .dout(addr_info), .valid(addr_info_valid),
        .empty(buffer_empty_info), .prog_full(buffer_full_info));

    assign addr_buffer_full = buffer_full_offset || buffer_full_info;

    always @ (posedge clk) begin
        if (front_rst) begin
            mem_data_to_edge_off <= 0;
            mem_data_valid_to_edge_off <= 1'b0;

            mem_data_to_edge_info <= 0;
            mem_data_to_edge_degree <= 0;
            mem_data_valid_to_edge_info <= 1'b0;
        end
        else begin
            if (mem_data_valid_offset) begin
                mem_data_to_edge_off <= mem_data_offset;
                mem_data_valid_to_edge_off <= 1'b1;
            end
            else begin
                mem_data_to_edge_off <= 0;
                mem_data_valid_to_edge_off <= 1'b0;
            end
            if (mem_data_valid_info) begin
                mem_data_to_edge_info <= mem_data_info;
                mem_data_to_edge_degree <= mem_data_degree;
                mem_data_valid_to_edge_info <= 1'b1;
            end
            else begin
                mem_data_to_edge_info <= 0;
                mem_data_to_edge_degree <= 0;
                mem_data_valid_to_edge_info <= 1'b0;
            end
        end
    end
endmodule
